package com.bz.zhrc.service;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bz.zhrc.config.BizConstant;
import com.bz.zhrc.dto.DeviceReq;
import com.bz.zhrc.dto.OrgReq;
import com.bz.zhrc.dto.Organ;
import com.bz.zhrc.dto.WlDeviceReq;
import com.bz.zhrc.util.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@Slf4j
public class PushService {

    private static final Map<String,String> sessionMap = new ConcurrentHashMap<>();
    private static final AtomicInteger deviceCount = new AtomicInteger();
    private static final AtomicInteger logCount = new AtomicInteger();
    private static final AtomicInteger searchCount = new AtomicInteger();

    /**
     * 获取sessionId
     * @return
     */

    /**
     *
     * @return
     */
    public String getSessionId(){
        String sessionId = sessionMap.get("sessionId");
        if (StringUtils.isNotBlank(sessionId)){
            return sessionId;
        }
        JSONObject obj = new JSONObject();
        obj.put("account",BizConstant.lz_username);
        obj.put("password",BizConstant.lz_password);
        String resp = HttpRequest.post("http://10.1.237.121:8000/api-usersystem/user/login?loginName=gis&password=196e9f5844705915fa8b47cb048b3523").timeout(3000).execute().header("Authenticator");
        JSONObject jsonObject = JSONObject.parseObject(resp);
        JSONObject data = jsonObject.getJSONObject("data");
        if (null != data){
            log.info("sessionId获取成功！");
            sessionMap.put("sessionId",data.getString("sessionId"));
            return sessionMap.get("sessionId");
        }
        log.info("sessionId获取失败！");
        return "";
        
    }

    /**
     * 获得机构树
     * @return
     */
    public  List<String>  getTree(){
        List<String> ids = new ArrayList<>();
        deviceCount.set(0);
        logCount.set(0);
        searchCount.set(0);
        //携带SessionId的post请求，用String接到请求结果。获取机构树
        String resp = HttpRequest.post(BizConstant.ORG_TREE_URL).body(JSONObject.toJSONString(new OrgReq(getSessionId()))).timeout(3000).execute().body();
//        log.info("获得机构树请求结果：{}",resp);
        //把String类型的resp转换为JSONObject对象，获取里面的data字段
        String data = JSONObject.parseObject(resp).getString("data");
        //判断data是否为空，
        if (StringUtils.isNotBlank(data)){
            //不为空，就把data转换为Organ对象
            Organ organ = JSONObject.parseObject(data, Organ.class);
            List<Organ> organList = new ArrayList<>();
            organList.add(organ);
            findId(organList,ids);
        }
        log.info("机构ids长度:{}",ids.size());
        return ids;
    }

    /**
     * 设备列表搜索接口
     * @param id
     */
    @Async
    public void getAndPushDevice(String id){
        try {
            log.info("设备列表搜索接口调用次数：{}", searchCount.incrementAndGet());
            //通过post请求携带SessionId和id查询设备的信息，用String类型来接
            String resp = HttpRequest.post(BizConstant.DEVICE_QUERY_URL).body(JSONObject.toJSONString(new DeviceReq(getSessionId(), "", id, true))).timeout(3000).execute().body();
            log.info("设备列表搜索接口请求结果：{}", resp);
            //把Sting字符串转换成JSONObject对象
            JSONObject jsonObject = JSONObject.parseObject(resp);
            //获取data字段并转化为JSONArray集合
            JSONArray array = jsonObject.getJSONArray("data");
            //判断是否为空
            if (null != array) {
                array.forEach(item -> pushDevice((JSONObject) item));
            }
        }catch (Exception e){
            log.info("超时:{}",e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 基础数据上报
     * @param jo
     */
    public void pushDevice(JSONObject jo){
        String token = getToken();
        WlDeviceReq req = new WlDeviceReq();
        req.setSensorType("51");
        req.setSensorName("网络监控摄像机");
        req.setApplyId("YY000006");
        req.setCityId("510100000000");
        req.setAreaId("510101400000");
        req.setRegionId("510101400001");
        req.setProjectCode("5");
        req.setCommissionCode("WB510100000003");
        req.setCommissionName("成都市网络理政办");
        req.setDataCode("DATA_AOSGZCQR_1");
        req.setConnectType("WiFi");
        req.setProtocol("HTTP");
        req.setSensorId(jo.getString("id"));

        //判断camName是否为空，为空就拼接地址和id，
        req.setAddress(StringUtils.isBlank(jo.getString("camName"))?"成都市"+jo.getString("id"):jo.getString("camName"));
        String lat = jo.getString("y");
        //判断经度是否为空和长度是否大于3，
        req.setWsLat(StringUtils.isNotBlank(lat)&&lat.length()>3?lat:"");
        String lng = jo.getString("x");
        req.setWsLng(StringUtils.isNotBlank(lng)&&lng.length()>3?lng:"");

        List<Object> list = new ArrayList<>();
        list.add(req);
        //把Java对象转换成String类型的JSON字符串
        String reqStr = JSONObject.toJSONString(list);
        log.info("推送设备基础信息：{}",reqStr);
        //连接平台基础数据上报接口
        String resp = HttpRequest.post(BizConstant.PUSH_DEVICE_URL).body(reqStr).header("Authenticator",token).timeout(3000).execute().body();
        log.info("推送设备基础信息结果：{}",resp);
        //加1
        log.info("推送设备基础信息累计数量：{}", deviceCount.incrementAndGet());
        //判断isOnline是否为true
        if(jo.getBooleanValue("isOnline")){
            //为true就执行pushLog方法
            pushLog(jo.getString("id"));
        }
    }

    /**
     * 日志上报
     * @param deviceId
     */
    public void pushLog(String deviceId){
        //获取日期转化为对应格式
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("dataCode","DATA_AOSGZCQR_1");
        //存入id和时间
        jsonObject.put("deviceId",deviceId);
        jsonObject.put("postTime", now);
        JSONObject job = new JSONObject();
        job.put("device_id",deviceId);
        job.put("received_time",now);
        job.put("f_cnt_up","1");
        jsonObject.put("data",job);
        log.info("推送日志请求串：{}",jsonObject.toJSONString());
        //连接平台日志上报接口
        String response = HttpRequest.post(BizConstant.PUSH_LOG_URL).body(jsonObject.toJSONString()).timeout(3000).execute().body();

        log.info("推送日志请结果：{}",response);
        log.info("推送日志请累计数量：{}",logCount.incrementAndGet());
    }

    /**
     * 获取平台token
     * @return
     */
    public String getToken(){
        return HttpRequest.get(BizConstant.LOGIN_URL)
                .form("loginName",BizConstant.wl_username)
                .form("password", MD5Util.md5(BizConstant.lw_password))
                .execute().header("Authenticator");
    }

    public void findId(List<Organ> organList,List<String> list){

        organList.forEach(organ -> {
            //判断是否还有下一级
            if (null == organ.getChildOrgan() || organ.getChildOrgan().isEmpty()) {
                list.add(organ.getId());
            }else {
                findId(organ.getChildOrgan(),list);
            }
        });
    }

}
